package com.lms.admin.base.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lms.admin.base.mapper.SysMenuMapper;
import com.lms.admin.base.req.SysRoleMenuReq;
import com.lms.admin.base.service.ISysMenuService;
import com.lms.admin.base.service.ISysRoleMenuService;
import com.lms.admin.base.vo.MenuNode;
import com.lms.common.entity.SysMenu;
import com.lms.common.entity.SysRoleMenu;
import com.lms.common.web.service.impl.WrapperServiceImpl;
import com.lms.resource.service.utils.SecurityUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class SysMenuServiceImpl extends WrapperServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {

    private final ISysRoleMenuService sysRoleMenuService;

    @Override
    public IPage<?> queryMapper(Page<SysMenu> page, Map<String, Object> p) {
        return this.baseMapper.query(page, p);
    }

    @Override
    public List<MenuNode> getLoginMenu() {
        // 获取当前登录人的权限
        List<String> authorities = SecurityUtil.getAuthorities();
        // 查询出符合权限的所有菜单
        List<SysMenu> menus = this.baseMapper.selectByAuthorities(authorities);
        List<MenuNode> result = new ArrayList<>();
        for (int i = 0; i < menus.size(); i++) {
            SysMenu m = menus.get(i);
            if (m.getParentId() == null || m.getParentId() == -1) {
                result.add(new MenuNode(m));
                menus.remove(i);
                i--;
            }
        }
        result.forEach(r -> {
            executeTree(r, menus);
        });
        return result;
    }

    @Override
    public Boolean bindRoles(SysRoleMenuReq params) {
        Long menuId = params.getMenuId();
        List<Long> authorities = params.getAuthorities();
        sysRoleMenuService.removeByMenuId(menuId);
        // 再插入新的角色
        List<SysRoleMenu> roleMenus = new ArrayList<>();
        authorities.forEach(a -> {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setMenuId(menuId);
            sysRoleMenu.setRoleId(a);
            roleMenus.add(sysRoleMenu);
        });
        if (!roleMenus.isEmpty()) {
            sysRoleMenuService.saveBatch(roleMenus);
        }
        return true;
    }

    private void executeTree(MenuNode parentNode, List<SysMenu> menus) {
        for (int i = menus.size() - 1; i >= 0; i--) {
            if (i >= menus.size()) {
                continue;
            }
            SysMenu m = menus.get(i);
            if (parentNode.getId().equals(m.getParentId())) {
                MenuNode menuNode = new MenuNode(m);
                parentNode.addChild(menuNode);
                menus.remove(i);
                i++;
                executeTree(menuNode, menus);
            }
        }
    }
}
